Самый быстрый браузер

В июле 2023 года произошло важное событие — Firefox превзошёл Chrome в популярном тесте Speedometer, который измеряет скорость работы браузеров.

Были времена, когда Firefox считался медленным и неповоротливым браузером, потребляющим много памяти и в целом «тормозным». Когда появился Chrome, то некоторые пользователи перешли на него из-за лучшей производительности. Сейчас ситуация кардинально меняется.

Как Mozilla сумела добиться такого результата?

Оптимизация скорости

Разработчики Firefox долго и упорно работали над оптимизацией и устранением багов — и в конце концов эта работа дала эффект. Была установлена чёткая программа действий с измеримыми результатами.

В первую очередь Mozilla разработала и внедрила фреймворк Raptor для проведения автоматических тестов, чтобы измерять производительность своих продуктов — и интегрировала его в CI, то есть в стандартный процесс разработки и выпуска новых версий ПО. Другими словами, новые версии программ не выпускаются без предварительного бенчмарка. Автоматизацией тестов занимается отдельная группа девопсов PerfTest Team под руководством «шерифа по производительности» Дейва Ханта, опытного специалиста по автоматизации.

Два крупнейших скачка в производительности Firefox в марте-апреле 2023 года на графике связаны с двумя конкретными исправлениями: изменение обработки аттрибута autofocus в соответствии со спецификациями и динамическая настройка максимального размера «грязных» страниц в аллокаторе памяти mozjemalloc с увеличением этого размера для процессов с фоновым контентом.

В принципе, можно нажать на каждую точку на графике — и посмотреть, что изменилось с этим коммитом. Например, внезапные скачки в производительности Chrome связывают с изменениями в инфраструктуре тестирования.

Результаты Firefox и Chrome в разных тестах на всех платформах в более наглядном виде показаны здесь:

Как видим, Speedometer — не единственный бенчмарк, в котором Firefox удалось опередить конкурента. Хотя по многим другим тестам впереди Chrome.

Фреймворк Raptor запускается в среде Browsertime (Node.js, Selenium WebDriver) на Firefox Desktop, Firefox Android GeckoView, Fenix, Chromium и Chrome. Судя по списку программ, Mozilla выбрала в качестве ориентира именно Chrome. Поэтому мы не можем сравнить их с остальными браузерами в данной среде. Только друг с другом.

Raptor поддерживает три типа тестов:

  1. тесты на загрузку страниц;
  2. стандартные бенчмарки;
  3. «сценарные» тесты, например, измерение энергопотребления, процессора и памяти.

Список «стандартных бенчмарков» (пункт 2) состоит из стандартных независимых тестов, включая Speedometer 3 (sp3), MotionMark и JetStream. Тесты на загрузку страниц измеряют реальное время загрузки и рендеринга популярных сайтов, таких как YouTube и Википедия.

Список сайтов для измерения скорости загрузки страниц (десктопные тесты)

  • amazon
  • bing-search
  • buzzfeed
  • cnn
  • ebay
  • espn
  • expedia
  • facebook
  • fandom
  • google-docs
  • google-mail
  • google-search
  • google-slides
  • imdb
  • imgur
  • instagram
  • linkedin
  • microsoft
  • netflix
  • nytimes
  • office
  • outlook
  • paypal
  • pinterest
  • reddit
  • tumblr
  • twitch
  • twitter
  • wikia
  • wikipedia
  • yahoo-mail
  • youtube

Настройки одного из тестов:

  • alert on: fcp, loadtime, ContentfulSpeedIndex, PerceptualSpeedIndex, SpeedIndex, FirstVisualChange, LastVisualChange
  • alert threshold: 2.0
  • apps: firefox, chrome, chromium, safari, custom-car
  • browser cycles: 25
  • expected: pass
  • gecko profile entries: 14000000
  • gecko profile interval: 1
  • lower is better: true
  • page cycles: 25
  • page timeout: 60000
  • playback: mitmproxy
  • playback pageset manifest: mitm7-linux-firefox-youtube.manifest
  • playback version: 8.1.1
  • secondary url: https://www.youtube.com/watch?v=JrdEMERq8MA
  • test url: https://www.youtube.com
  • type: pageload
  • unit: ms
  • use live sites: false
  • Test Task:

В целом список тестов Raptor кажется максимально полным из того, что можно придумать для такой задачи. Это более объективная метрика, чем любой одиночный бенчмарк.

Примечание. В отдельных независимых тестах лучший результат по отдельным бенчмаркам могут показывать Edge, Safari или Opera. Так что звание «самого быстрого браузера» нельзя никому присудить однозначно, всё зависит от конкретного бенчмарка, версии браузера, включённых опций компиляции и флагов (настроек) браузера, а также платформы, на которой проводится тестирование (опции GPU-рендеринга, аппаратные функции CPU, настройки и версия ОС). Оптимальный вариант для пользователей — установить все интересующие браузеры на своём компьютере, запустить тесты на официальных сайтах (ссылки ниже) — и сравнить результаты в своей конкретной конфигурации. Вероятно, на macOS естественное преимущество получит Safari, а на Windows — Edge. Поскольку браузер и ОС в этих случаях разрабатывает одна компания (Apple и Microsoft, соответственно), она может применить некие общие системные оптимизации.

Chrome не сдаётся

Производительность можно измерять по-разному. В данный момент есть три основных бенчмарка для браузеров: Speedometer, MotionMark и JetStream.

В июне 2023 года разработчики Chrome заявили о достижении максимальных для себя результатов во всех трёх тестах. По их словам, чуть более чем за год результат Speedometer вырос с 300 (версия Chrome 101) до 491 (Chrome 116.0.5803.2 на M2 Macbook Air с включённым компилятором Maglev при сборке браузера).

Результат теста графической подсистемы MotionMark почти утроился с начала 2023 года до 4821,30 (Chrome M115.0.5773.4 на 13” M2 Macbook Pro).

Бенчмарк JetStream (JavaScript и WebAssembly, продвинутые веб-приложения) благодаря внедрению Maglev показал рост до 330,939 (Chrome 116.0.5803.2 на M2 Macbook Air с Maglev). Каков был прежний результат, не сообщается.

Обратим внимание, что тесты Google проводились на сборке Chrome с новым промежуточным JIT-компилятором Maglev, который «позволяет генерировать эффективный машинный код для всех релевантных функций в течение сотых долей секунды». По внутренним тестам, Maglev для движка V8 улучшил результат Jetstream на 7,5%, а Speedometer — на 5%.

На первый взгляд, результаты Google не очень сходятся с графиками Raptor, как будто они используют разные версии браузеров и бенчмарков (например, Speedometer 3 сильно отличается от Speedometer 2). Вопрос в том, какие тесты более соответствуют фактическому опыту пользователей.

Так или иначе, но соревнование разработчиков Firefox и Chrome на поле оптимизации можно только приветствовать.

Риск монополии

Некоторые специалисты считают, что нельзя допустить монополии Google Chrome на браузерном рынке на фоне того, часто всё больше сторонних браузеров переходят на движок и кодовую базу Chrome. В то же время аудитория Firefox продолжает снижаться. По статистике Mozilla, аудитория Firefox сократилась на 60 млн за четыре года, что составляет 24% аудитории (с пиковых 252 млн в 2019 году до 191 млн в июле 2023-го).

В такой ситуации появляются риски, что веб-сайты начнут разрабатывать в соответствии со стандартами, которые поддерживаются в Chrome, а не по официальным стандартам W3C. Недавняя история с удалением формата JPEG-XL из Chrome в октябре 2022 года стала хорошим индикатором нынешнего положения дел. Если бы не неожиданная поддержка со стороны Apple, этот качественный формат сжатия графики рисковал забвением. Однако на конференции WWDC23 компания Apple объявила о поддержке JPEG-XL во всех своих продуктах, включая Safari 17, новые версии iOS, iPadOS, macOS, watchOS и visionOS. Разработчики JPEG-XL с иронией восприняли тот факт, что первым браузером с поддержкой JPEG-XL стал Safari. Кто мог такое представить для формата, созданного при участии Google?

Монополия реально угрожает разработке новых форматов и перспективных технологий, которые могут оказаться на обочине истории по прихоти монополиста. Поэтому конкуренция со стороны Firefox очень важна для рынка браузеров, ведь Gecko по сути остался единственным независимым движком для рендеринга веб-страниц, не считая экспериментальных проектов Quantum и Servo от той же Mozilla.


ссылка на оригинал статьи https://habr.com/ru/articles/752862/

React Custom Hook: useScript

In this article series, we embark on a journey through the realm of custom React hooks, discovering their immense potential for elevating your development projects. Our focus today is on the «useScript» hook, one of the many carefully crafted hooks available in the collection of React custom hooks.

Github: https://github.com/sergeyleschev/react-custom-hooks

import useAsync from "../useAsync/useAsync"  export default function useScript(url) {     return useAsync(() => {         const script = document.createElement("script")         script.src = url         script.async = true         return new Promise((resolve, reject) => {             script.addEventListener("load", resolve)             script.addEventListener("error", reject)             document.body.appendChild(script)         })     }, [url]) }

One of the significant advantages of useScript is its ability to handle script loading asynchronously. By setting the script’s async attribute to true, you ensure that it won’t block the rendering of your application. This improves the performance and overall user experience, especially when dealing with larger scripts or slow network connections.

useScript can be used in various scenarios. For instance, you can load external libraries like jQuery, enabling you to harness its powerful functionalities without adding bulk to your bundle. Additionally, you can load analytics scripts, social media widgets, or any other script necessary for your application’s dynamic behavior.

import useScript from "./useScript"  export default function ScriptComponent() {     const { loading, error } = useScript(         "https://code.jquery.com/jquery-3.6.0.min.js"     )     if (loading) return <div>Loading</div>     if (error) return <div>Error</div>     return <div>{window.$(window).width()}</div> }

In the example above, we see how useScript is utilized in a ScriptComponent. The useScript hook is called with the URL of the jQuery library as an argument. The hook returns the loading and error states, which can be used to display a loading spinner or an error message accordingly. Once the script is successfully loaded, the component displays the current window width using jQuery.

Full Version | React Custom Hooks: https://habr.com/en/articles/746760/


ссылка на оригинал статьи https://habr.com/ru/articles/752822/

Мультиоблачная архитектура: проблемы и подводные камни

Одновременное использование нескольких облачных провайдеров в одной инфраструктуре — популярная модель, которую в перспективе рассматривают многие крупные компании. В этом посте мы рассмотрим сценарии перехода к мультиоблаку, возможные проблемы и некоторые ошибки, которые можно допустить, если вы всё-таки на это решились.

Что такое мультиоблако и какие пути к нему ведут 

Мультиоблако — это концепция использования услуг сразу нескольких облачных провайдеров для размещения сервисов. Компании прибегают к мультиоблаку, когда хотят добиться максимально подходящей для себя схемы получения услуг, избежать привязки к одному поставщику или создать задел на масштабирование инфраструктуры.

Развитие подобной инфраструктуры обычно начинается с одного облака. Компания выбирает облачного провайдера и переносит к нему необходимые приложения. Далее начинает присматриваться и к другим облачным провайдерам, планируя наиболее выгодные комбинации. AWS и Azure часто используют для контейнеризированных систем, GCP (облако Google) — для больших объемов данных и машинного обучения. Так постепенно формируется мультиоблако. Иногда поиск новых провайдеров связан с ограничениями местных регуляторов или жесткими требованиями к непрерывности бизнеса. Здесь появляется и такой вариант, как портативное облако — когда приложение является cloud-agnostic, то есть не имеет специфических требований и может быть развернуто на любой конфигурации облачных инфраструктур.

В конце концов, компании могут вырасти до архитектуры распределенного облака, где сочетаются и локальные ресурсы, и различные облачные инфраструктуры. Так работают крупные телеком-провайдеры и другие географически распределенные компании. Другая, вынужденная причина перехода к мультиоблачной модели — это покупка одной головной организацией нескольких новых компаний, у каждой из которых есть облачная инфраструктура, привязанная к своим провайдерам.

Проблемы мультиоблака по сравнению с выбором одного провайдера

Основные проблемы мультиоблачной инфраструктуры связаны с ее автоматизацией. Если вы используете AWS CloudFormation для облака Amazon и Google Deployment Manager для облака Google, то, вероятно, вам придется прописывать все свои политики отдельно для каждого провайдера — даже самые простые правила вроде допустимых конфигураций виртуальных машин. Здесь есть смысл прибегнуть к IaS-инструментам (Infrastructure as Code), таким как, например, Terraform.

Упоминая мультиоблако, люди нередко подразумевают именно создание портативных, cloud-agnostic приложений — эту концепцию мы упоминали несколько абзацев назад. Такой подход требует дополнительных затрат, поэтому стоит предварительно убедиться, действительно ли вам нужен cloud-agnostic подход и какие преимущества он даст именно в вашем случае. «Мы хотим двигаться в сторону cloud-agnostic, потому что для компании стратегически важно иметь поддержку различных облаков» — если это всё, к чему вы пришли, подумайте еще раз, конкретнее. Возможно, вы привязаны к жесткому SLA в пользовательском приложении, но при этом ориентируетесь на active-active или active-passive облачную инфраструктуру? Да, это один из случаев, когда cloud-agnostic может себя оправдать.

При этом cloud-agnostic подход предполагает, что вы сознательно оградите себя от всей функциональности, которая не является общей у возможных платформ. Все автоматизации, которые удобно организованы на той или иной платформе, придется отбросить — а это неизбежно приведет к дополнительным расходам. Если вы решите перевести на cloud-agnostic модель всю компанию — расходы вырастут еще больше. С другой стороны, вы можете выбрать единственную наиболее подходящую вам платформу и использовать ее по максимуму, со всеми фичами — это сэкономит ресурсы.

Для аналогии здесь можно привести две модели создания сложных программных комплексов, когда-то распространенные в индустрии — с использованием реляционных БД SQL или стандартизированной модели J2EE. Для первого решения существует общепринятый стандарт ANSI, на его возможности настолько слабы, что без проприетарных надстроек от вендоров эта модель бесполезна. Поэтому если вы выбираете конкретного вендора SQL, то становитесь привязаны к нему на уровне инфраструктуры. J2EE была разумной альтернативой такого вендор-лока до тех пор, пока в этой сфере не распространились решения на открытом коде.

Использование всеми облачными провайдерами какого-нибудь общего API было бы идеально — но не для самих провайдеров. Ведь они работают по подписной модели, живут на ваши регулярные платежи, а значит, не заинтересованы в том, чтобы вы могли взять и легко уйти к конкуренту. Нет, вас будут привлекать всеми возможными «уникальными фичами», чтобы вы как можно глубже увязали именно в одной экосистеме.

Очень важно систематизировать нагрузочные потоки приложений. Если размещать в облаке нечто реально критичное для бизнеса, то возникают определенные риски. Да, cloud agnostic — это выход: но будьте готовы к дополнительным расходам и отказу от вендорских «вишенок на торте».

Мировой рынок провайдеров облачной инфраструктуры в 1 квартале 2023 года (модели IaaS, Paas и частные облака)

Мировой рынок провайдеров облачной инфраструктуры в 1 квартале 2023 года (модели IaaS, Paas и частные облака)

Что стоит учитывать при переходе от одного облака к мультиоблаку

Начать, конечно же, стоит с формирования реальной цели на уровне бизнеса. Нужен четкий сценарий, какие проблемы бизнеса вы можете решить с помощью перехода на мультиоблако. Кроме того, переход на мультиоблако потребует от команды новых компетенций — учтите это. Подумайте о расходах: облака уже давно перестали быть сравнительно дешевыми, и добавление нового провайдера непременно увеличит бюджеты.

Далее при планировании автоматизации стоит по возможности придерживаться cloud-agnostic решений. Для деплоя и интеграции можно выбрать уже упомянутый Terraform, для защиты — Hashicorp, для раскатки политик — Open Policy Agent. Подойдите к этому более глобально, с учетом потенциальных потребностей и изменений в будущем.

Иногда о мультиоблаке задумываются для того, чтобы гарантировать работу бизнес-критичных приложений в разных регионах. Но прежде чем планировать такой переход, убедитесь: а ваш текущий, единственный облачный провайдер точно не способен обеспечить требуемую инфраструктуру во всех зонах доступности? Если вам необходим disaster recovery, то, может, будет логичней создать его в другой зоне доступности вашего текущего провайдера?

Если вы работаете в пределах одного провайдера, у вас есть один-единственный, отлаженный набор инструментов для разных целей. Но при подключении второго провайдера вы получаете другой аналогичный набор, и для каждого сценария появляется альтернатива. Да, есть перспектива собрать более удачный, комбинированный набор инструментов, но обязательно изучите, насколько совместимы между собой компоненты от разных провайдеров.

Другой важный вопрос — мониторинг. Если вам нужно будет сравнить данные. У каждого провайдера есть для этого свои инструменты, поэтому, если вы не можете поставить рядом несколько экранов при любой необходимости, подумайте о том, как объединить мониторинг в рамках одного инструмента — например, New Relic или Datadog.

Если обобщить и дополнить сказанное выше, можно выделить пять направлений для описания требований и оценки перехода на мультиоблако:

  • расходы на инфраструктуру;

  • идентификация и доступ;

  • реализация внутренних политик;

  • выделение и развертывание ресурсов;

  • мониторинг.

Антипаттерны работы в мультиоблачной модели

Напоследок выделим ряд опасных ситуаций, связанных с работой в мультиоблачной модели.

Не стоит планировать такой переход, если у вас отсутствуют универсальные метрики для деплоя приложений. Бывает, что один юнит в пределах организации использует AWS, другой начинает использовать GCP; без некоего общего знаменателя вы просто не оцените результат преобразований .

Второй антипаттерн связан с используемыми инструментами. Доступ к новым инструментам — это большой соблазн сконцентрировать внимание на них вместо того, чтобы попробовать выжать максимум из того, что есть. Так постепенно сформируется зоопарк решений — и целый сад подводных камней, связанных с их совместным использованием. Перед тем как расширять этот зоопарк, остановитесь и подумайте: а нельзя ли использовать уже имеющееся решения для этих задач?

Еще один вопрос связан с управлением — если, например, вы используете контейнеры в разных средах, то как вы организуете для них единые политики? Оцените возможные инструменты для этого — Rancher, Kublr, IBM Satellite, Google Anthos или что-нибудь еще.

Не стоит задумываться о мультиоблаке, если у вас в принципе не было опыта работы с облачными провайдерами. Некоторые начинают свой путь с того, что сразу выбирают пару провайдеров, у которых будет крутиться приложение. Выбрать Azure и GCP? Или AWS и Azure? Начинайте с чего-нибудь одного, а потом уже будет логично задуматься о совместимости. Иначе есть риск столкнуться с проблемами, которые съедят очень много времени — потому что вам придется разбираться как с работой каждого облака, так и с их совместимостью.

Выбор в пользу мультиоблака стоит тщательно продумать и оценить на разных уровнях. И чем меньше ваша компания, тем больше вероятность, что все вопросы разумнее решить в пределах одного провайдера. Текущего или альтернативного, но одного. А если уж вы решились на переход, то задумайтесь сразу и о том, как максимально унифицировать работу на всех уровнях в пределах всех провайдеров. В будущем это предотвратит немало проблем.


ссылка на оригинал статьи https://habr.com/ru/articles/752850/

React Custom Hook: useTimeout

In this article series, we embark on a journey through the realm of custom React hooks, discovering their immense potential for elevating your development projects. Our focus today is on the «useTimeout» hook, one of the many carefully crafted hooks available in the collection of React custom hooks.

Github: https://github.com/sergeyleschev/react-custom-hooks

import { useCallback, useEffect, useRef } from "react"  export default function useTimeout(callback, delay) {     const callbackRef = useRef(callback)     const timeoutRef = useRef()     useEffect(() => {         callbackRef.current = callback     }, [callback])     const set = useCallback(() => {         timeoutRef.current = setTimeout(() => callbackRef.current(), delay)     }, [delay])     const clear = useCallback(() => {         timeoutRef.current && clearTimeout(timeoutRef.current)     }, [])     useEffect(() => {         set()         return clear     }, [delay, set, clear])     const reset = useCallback(() => {         clear()         set()     }, [clear, set])     return { reset, clear } }

The «useTimeout» hook encapsulates the logic for setting, clearing, and resetting timeouts within a React component. It takes two parameters: a callback function and a delay duration in milliseconds. Whenever the specified delay elapses, the provided callback function is executed.

One of the significant advantages of this custom hook is that it ensures the callback function remains up to date even if it changes during component re-renders. By using a useRef to store the callback reference, the hook guarantees that the latest version of the function is always called.

Moreover, the «useTimeout» hook optimizes performance by utilizing useCallback to memoize the «set» and «clear» functions. This means that the functions are only recreated when their dependencies change, preventing unnecessary renders and enhancing efficiency.

import { useState } from "react" import useTimeout from "./useTimeout"  export default function TimeoutComponent() {     const [count, setCount] = useState(10)     const { clear, reset } = useTimeout(() => setCount(0), 1000)     return (         <div>             <div>{count}</div>             <button onClick={() => setCount(c => c + 1)}>Increment</button>             <button onClick={clear}>Clear Timeout</button>             <button onClick={reset}>Reset Timeout</button>         </div>     ) }

The «useTimeout» hook can be utilized in various scenarios where timed actions are required. For example, in a countdown component like the «TimeoutComponent» showcased above, you can easily implement a timer that resets after a specific duration. By using the «useTimeout» hook, you can effortlessly update the countdown value and manage the timeout without worrying about complex timeout management code.

Full Version | React Custom Hooks: https://habr.com/en/articles/746760/


ссылка на оригинал статьи https://habr.com/ru/articles/752832/

Приложения алгебры кортежей. Часть 1. Гибкая система счисления с простыми основаниями

В настоящее время известно большое число систем счисления. Подробный перечень (не знаю, насколько полный) приведен в англоязычной Википедии. В этом списке я не нашел ту систему, которая будет изложена здесь. Она относится к классу систем с переменным основанием (mixed radix). Предлагаю ее назвать Flexible number system with a Prime Radixes, сокращенно FPR-системой счисления.

Но для того, чтобы ее понять, необходимы знания некоторых понятий алгебры кортежей (АК) и частично упорядоченных множеств хотя бы в том объеме, который имеется в соответствующей статье в Википедии. Об АК кратко было рассказано в статье «Как совместить логику и семантику в одной алгебраической системе». Там же есть ссылки на публикации с более подробным описанием АК.

В данной статье будут обоснованы следующие преимущества предложенной системы счисления:

  • она универсальна — позволяет ТОЧНО выразить все (за исключением нуля) конечные целые и рациональные (с любым ненулевым целым числом в знаменателе) числа, а также некоторые классы иррациональных чисел;

  • ее использование позволяет сократить вычислительную сложность алгоритма умножения чисел;

  • в ней существенно уменьшается объем памяти для записи и хранения многих больших чисел.

Свойство гибкости

Для понимания данного текста важную роль играют такие понятия АК как схема отношения, фиктивная компонента и обобщенные операции. Напомню, что атрибуты – это имена переменных, домены – множества, задающие области значений атрибутов, схема отношения — заключенная в прямые скобки последовательность атрибутов, фиктивные компоненты в АК – это предельные значения доменов атрибутов: \ast — множество всех значений соответствующего атрибута (полная компонента) и \varnothing (пустая компонента).

Обобщенные операции – это операции с АК-объектами, имеющими разные схемы отношения. Для выполнения этих операций АК-объекты предварительно приводятся к одной схеме отношения с помощью простой операции добавление фиктивного атрибута. В частности, в ПРИМЕРе статьи Подсказки 1 и 2 («Во второй комнате нет тигра, а третья комната не пуста», «Первая комната не пуста, а во второй нет тигра») можно было выразить в сокращенных схемах отношения
\quad \quad M_1[R_2R_3] = [\{L,E\} \quad \{L,T\}] и
\quad \quad M_2[R_1R_2] = [\{L,T\} \quad \{L,E\}].

Затем вычислить дополнение Подсказки 2 в сокращенной схеме отношения
\overline{M_2}[R_1R_2] = \begin{bmatrix} \{E\} & * \\ * & \{T\} \end{bmatrix}
и вычислить обобщенное пересечение, предварительно добавив на место отсутствующих фиктивные атрибуты,
M_1[R_2R_3] \cap_G \overline{M_2}[ R_1R_2] = [\ast \quad \{L,E\} \quad \{L,T\}] \cap \begin {bmatrix} \{E\} & * & *\\ * & \{T\} & * \end{bmatrix} = [\{E\}\quad \{L,E\} \quad \{L,T\}].

Результат получился тот же самый.

Аналогично определяются и обобщенные отношения: объекты с разными схемами отношения перед проверкой равенства или включения приводятся к одинаковым схемам отношения с помощью добавления фиктивных атрибутов.

Обобщенные операции и отношения как раз и обеспечивают в математической системе свойство гибкости.

Стоит отметить, что схема отношения, с помощью которой можно придать системе свойство гибкости, полезна и в других разделах математики помимо реляционной алгебры, например, в теории функций многих переменных. Иногда это помогает упростить изложение, а в некоторых случаях избежать серьезных ошибок. Например, в логическом выводе на основе исчисления предикатов схема отношения не используется, в результате чего разрешается замена переменных в алгоритме унификации. Это приводит к тому, что в некоторых случаях искажаются заданные условия исходной задачи. Об этом можно прочитать в статье «Как вычислять интересные следствия» (с. 165).

Решетка числовых кортежей

Для представления чисел в FPR-системе счисления будут использоваться числовые n-кортежи (т.е. кортежи чисел длины n).

Решетка – это частично упорядоченное множество (сокращенно у-множество (poset)), для которого определены две операции: точная нижняя грань (обозначается inf или \wedge) и точная верхняя грань (обозначается sup или \vee). В общем случае эти операции выполняются для всех пар элементов решетки, но бывают другие варианты (нам они не понадобятся). В отличие от просто верхней (или нижней) грани точная верхняя (нижняя) грань дает в результате единственный элемент решетки.

Рассмотрим у-множество, элементами которого являются числовые n-кортежи. Введем для них отношение порядка \sqsubseteq (обычно отношение порядка в общем случае для у-множеств обозначается \leq, но мы этот знак будем здесь использовать для отношения «меньше или равно» для обычных чисел). Пусть даны числовые n-кортежи A=(a_1, a_2, \cdots, a_n) и B=(b_1, b_2, \cdots, b_n). Определим для них отношение порядка и операции.

  • A \sqsubseteq B подтверждается, если и только если a_i \leq b_i для всех i = 1, 2,\ldots, n. В противном случае n-кортежи не сравнимы.

  • A \wedge B = (min(a_1, b_1), min(a_2, b_2), \cdots, min(a_n, b_n)).

  • A \vee B = (max(a_1, b_1), max(a_2, b_2), \cdots, max(a_n, b_n)).

Если числа, содержащиеся в n-кортежах, ограничить наибольшим и наименьшим значениями величины, то мы получим решетку, что вообще-то несложно доказать.

Помимо «решеточных» операций \wedge и \vee для числовых кортежей можно ввести «экзотические» операции, например, сложение и вычитание:

  • A + B = ((a_1 + b_1), (a_2 + b_2), \cdots, (a_n + b_n)).

  • A - B = ((a_1 - b_1), (a_2 - b_2), \cdots, (a_n - b_n)).

Пока неясно, для чего они нужны, но дальше все станет понятным.

FPR-система счисления

Для числовых n-кортежей введем следующие обозначения и определения.
Рассмотрим возрастающий ряд простых чисел без пропусков и введем для них соответствующие обозначения P_i:

\begin{matrix}  P_1 & P_2 & P_3 & P_4 & P_5 &  \cdots & P_{15} & \cdots & P_{84} & \cdots & P_{169} & \cdots \\ 2 & 3 & 5 & 7 & 11 & \cdots & 47 & \cdots & 433 & \cdots & 1009 & \cdots \end{matrix}

Переменные P_i будем использовать в качестве атрибутов числовых кортежей, строго соблюдая порядок в схемах отношений: атрибут P_m расположен после атрибута P_k лишь при условии k < m.

Сначала рассмотрим вариант, в котором компонентами наших числовых кортежей будут неотрицательные целые числа. Они будут обозначать степени соответствующих простых чисел. Как известно, любое целое число можно разложить на простые множители. Например,
484 = 2 \cdot 2 \cdot 11 \cdot 11 = 2^2 \cdot 11^2. Тогда, если использовать схему отношения, получим следующую запись этого числа с помощью числовых кортежей:
484 \Rightarrow N_i[P_1P_5](2, 2) (после схемы отношения числа записывается числовой кортеж, с помощью которого это число можно выразить в позиционной системе счисления).

В качестве компонент в числовых кортежах допускаются отрицательные числа. Это позволяет отобразить в FPR-системе счисления любое положительное рациональное число. Например,
\frac {33} {40}\Rightarrow N_k[P_1P_2P_3P_5](-3, 1, -1, 1).

Известно, что любое число в степени 0 равно 1. Тогда можно считать, что компонента 0 в числовом кортеже играет роль фиктивной компоненты.

Например, число 484 можно выразить не только в схеме отношения [P_1P_5], но и, допустим, в схеме отношения [P_1P_2P_4P_5]:

484 = 2^2 \cdot 3^0 \cdot 7^0 \cdot 11^2 \Rightarrow N_m[P_1P_2P_4P_5](2, 0, 0, 2).

Отсюда ясно, что с помощью фиктивных компонент и соответственно фиктивных атрибутов можно выполнять операции с числами, у которых числовые кортежи имеют разные схемы отношения. В качестве примера вычислим произведение чисел 1176 и 495, используя числовые кортежи. Запишем эти числа в FPR-системе счисления:

1176 \Rightarrow N_1[P_1P_2P_4](3, 1, 2).

495 \Rightarrow N_2[P_2P_3P_5](2, 1, 1).

Ясно, что схемы отношения у этих чисел разные, но мы можем сделать их одинаковыми, добавив недостающие фиктивные атрибуты. Тогда получим

1176 \Rightarrow N_1[P_1P_2P_3P_4P_5](3, 1, 0, 2, 0).

495 \Rightarrow N_2[P_1P_2P_3P_4P_5](0. 2, 1, 0, 1).

Теперь, чтобы вычислить произведение этих чисел, нам достаточно вычислить «сумму» этих числовых кортежей, т.е. выполнить покомпонентное сложение. Получим
N_3[P_1P_2P_3P_4P_5](3. 3, 1, 2, 1) \Rightarrow 2^3 \cdot 3^3 \cdot 5 \cdot 7^2 \cdot 11 = 582120.

Операции в FPR-системе счисления

  • Обобщенное сложение (+_G): после добавления недостающих фиктивных атрибутов в числовых кортежах вычисляются суммы соответствующих компонент. Эта операция соответствует произведению исходных чисел.

  • Обобщенное вычитание (-_G): после добавления недостающих фиктивных атрибутов в числовых кортежах вычисляются разности соответствующих компонент. Эта операция соответствует делению исходных чисел.

Например, вычислим результат деления 495 на число 1176. В результате получим
(0. 2, 1, 0, 1) - (3, 1, 0, 2, 0) = (-3, 1, 1, -2, 1)

По полученному числовому кортежу восстановим число
N_4[P_1P_2P_3P_4P_5](-3, 1, 1, -2, 1) \Rightarrow \frac {3 \cdot 5 \cdot 11} {2^3 \cdot 7^2}= \frac {165} {392}.

  • Обобщенная нижняя грань (\wedge_G): если числовые кортежи содержат только неотрицательные целые числа, то тут все понятно – мы вычисляем наибольший общий делитель (НОД) двух исходных чисел. А если в числовых кортежах содержатся отрицательные целые числа, тогда что? Нетрудно доказать, что это наибольшее рациональное число, результатом деления на которое исходных рациональных чисел, получатся целые числа.

  • Обобщенная верхняя грань (\vee_G): для числовых кортежей с неотрицательными целыми числами вычисляется наименьшее общее кратное (НОК) исходных чисел.

  • Умножение на константу (имеется в виду умножение всех элементов числового кортежа на одну и ту же константу). Если константа – целое положительное k, то тут все понятно: исходное число возводится в степень k. А если константа дробь? Тоже ничего сверхъестественного: исходное число возводится в дробную степень. Тем самым появляется возможность выразить в FPR-системе счисления иррациональные числа.

  • Отрицательные исходные числа. Приведенные операции с числовыми кортежами показывают, что их элементами могут быть отрицательные и рациональные числа. С помощью таких числовых кортежей можно выразить все положительные целые, рациональные и некоторые классы иррациональных чисел (те, у которых сомножители являются результатом вычисления дробных степеней целых чисел). Невыразимо в этой системе точное значение нуля и отрицательные числа. Но с отрицательными числами положение можно легко исправить. Введем еще один атрибут P_0 = -1. Тогда четное целое значение соответствующего элемента в числовом кортеже означает, что мы имеем дело с положительными исходными числами, если же соответствующее число в кортеже целое нечетное, то исходное число отрицательное.

А возможны ли для атрибута P_0 другие значения в числовых кортежах? На ум приходит число \frac 1 2. В этом случае нашему взору откроется мнимое число.

Отношения в FPR-системе счисления

Обозначим исходные числа в позиционной системе счисления, которым соответствуют числовые кортежи A и B, соответственно N(A) и N(B).

  • Обобщенное отношение частичного порядка (\sqsubseteq_G). Если в числовых кортежах содержатся только неотрицательные целые числа, то это отношение соответствует известному отношению делимости (\mid) для множества положительных целых чисел. Если числовые кортежи содержат отрицательные целые числа, то исходные числа могут быть и дробями, но при этом если A \sqsubseteq_G B, то можно легко доказать, что результатом деления \frac {N(B)} {N(A)} будет целое число. Это обстоятельство позволяет ввести новое отношение порядка по делимости не только для целых, но и для рациональных чисел (\mid_R). А вот как интерпретируются случаи, когда в числовых кортежах содержатся несократимые дроби, пока непонятно.

  • Отношение порядка по величине. Ясно, что если A \sqsubseteq_G B, то всегда верно N(A) \le N(B). Это можно легко доказать, используя свойство неубывания показательной функции a^x, где

    x — неотрицательное действительное число.

Но если A \sqsubseteq_G B не соблюдается, то сравнение N(A) и N(B) по величине с помощью числовых кортежей становится проблемой.

Нерешенные проблемы

Хотя теории FPR-систем счисления пока что нет, но проблемы уже возникли. Но, может быть, это обстоятельство как раз и увеличивает шансы перехода данных заметок в теорию?

  1. Проблема сравнения чисел по величине. Из предыдущего ясно, что из A \sqsubseteq_G B следует N(A) \le N(B). Но если отношение порядка для числовых кортежей не соблюдается, то как проверить отношение порядка по величине для исходных чисел, не переводя их в позиционную систему счисления с постоянным основанием? Ответа на это вопрос нет, как нет и доказательства того, что такой алгоритм проверки для общего случая невозможен.

  2. Проблема суммирования. Используя FPR-систему счисления, можно легко вычислить произведения и рациональные степени соответствующих чисел. Но можно ли построить алгоритмы для вычисления суммы чисел, не переводя их в традиционную систему счисления?

В процессе развития новой теории, несомненно, появятся и другие проблемы.

Позитивные моменты

  1. Предложенная система позволяет точно выразить все конечные рациональные (за исключением 0) числа и некоторые классы иррациональных чисел.

  2. Нетрудно проверить, что вычислительная сложность алгоритма вычисления произведения чисел в FPR-системе счисления линейно зависит от числа атрибутов (n) в обобщенной схеме отношения этих чисел, что соответствует оценке O(n) вычислительной сложности. Эта оценка существенно меньше оценок вычислительной сложности известных алгоритмов для традиционных систем счисления. Здесь возможно следующее возражение: но ведь перевод числа из FPR-системы счисления в традиционную требует немалых вычислительных ресурсов, которые не учитываются при оценке вычислительной сложности этого алгоритма для FPR-системы.

Отвечаю: все правильно, но всегда ли нам нужен такой перевод? Например, в промежуточных вычислениях можно обойтись и без перевода.

  1. Для многих больших чисел FPR-система счисления позволяет значительно сэкономить место в памяти. Для тех, кто сомневается в этом, предлагаю сравнить объемы памяти для хранения записи N[R_4R_{181}](3, 100) и соответствующего ей числа N, выраженного в традиционной системе счисления.

Заключение

Не исключено, что у этих заметок есть шанс стать основой для нового раздела в теории чисел. Впрочем, дойдет ли дело до этого, неизвестно. Сам я этим вряд ли займусь. Во-первых, потому что непрофессионал в теории чисел, а, во-вторых, мне более близки проблемы, связанные другими приложениями алгебры кортежей.

Но если кто-то всерьез займется этой проблемой, то на соавторстве не буду настаивать. И не буду возражать, если найдется более подходящее название для этой системы счисления. Например, можно назвать просто и без затей: К-система (не подумайте плохого: под буквой «К» подразумевается не моя фамилия, а слово «Кортеж»).

Но от ссылки на эту статью не откажусь.

На форуме dxdy (https://dxdy.ru/topic155252.html ) предложили программу на языке PARI/GP, с помощью которой заданное целое число в десятичной системе счисления можно преобразовать в запись этого числа в FPR-системе, причем в формате TeX. Пример работы программы (перевод числа 1234567890 в FPR-запись):

? fpr(1234567890)

1234567890_{10}=[P_{1}P_{2}P_{3}P_{504}P_{529}](1,2,1,1,1)

А вот код программы ( с разрешения автора):

[code]fpr(x)=my(f=factor(x),n=#f[,1]);print1(«$»,x,»_{10}=«);for(i=1,n,print1(«P_{«,primepi(f[i,1]),»}»));print(«$»)[\code]

Продолжение следует.

Дизайн баннера выполнен Анной Горской


ссылка на оригинал статьи https://habr.com/ru/articles/752836/